package org.atlantis.juc.actor;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class Dispatcher {

	private static class Holder {
		static Dispatcher instance = new Dispatcher();
	}

	static Dispatcher getInstance() {
		return Holder.instance;
	}

	private ExecutorService executor = Executors.newCachedThreadPool();

	void readyToExecute(final Actor<?> actor) {
		if (actor.isExited()) return;
		boolean success = actor.context.status.compareAndSet(ActorContext.WAITING, ActorContext.EXECUTING);
		if (!success) return;
		executor.execute(new Runnable() {
			@Override
			public void run() {
				actor.execute();
				if (actor.isExited()) {
					actor.context.status.set(ActorContext.EXITED);
					return;
				}
				actor.context.status.set(ActorContext.WAITING);
				if (actor.getMessageCount() > 0) readyToExecute(actor);
			}
		});
	}
}
